﻿using Wabo.Dal.Interface;
using Wabo.Web.Areas.Manager.Core;
using Wabo.Web.Resources;
using System.Web.Mvc;
using Wabo.Web.Areas.Manager.ViewModels;
using System;
using Wabo.Util;

namespace Wabo.Web.Areas.Manager.Controllers
{
    public class LogonController : WaboController
    {
        private const string LogonAttemptCounterKey = "LOGON_ATTEMPT_COUNTER_KEY";
        private const string LogonCookieName = "WABO_LOGIN_DATA";
        

        private string CreateCookie(Dal.User usr)
        {
            return Crypto.Base64Encode( usr.id + ":" + usr.password );
        }

        private Dal.User GetUserFromLoginCookie(string cookieData)
        {
            cookieData = Crypto.Base64Decode(cookieData);
            var loginData = cookieData.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries);
            int userId = Int32.Parse(loginData[0]);
            string passwordHash = loginData[1];
            Dal.User usr = UserContext.Get(userId);
            if (usr != null && usr.password == passwordHash)
                return usr;
            return null;
        }

        private ActionResult AuthorizeUserAndSetCookie(string userName,string domain="",bool addCookie=false)
        {
            var authorizedUser = UserContext.Get(userName,domain);
            SessionManager.Authorize(authorizedUser);
            if( addCookie )
                AddCookie(LogonCookieName,CreateCookie(authorizedUser));
            LogEvent(LogOperation.Login, string.Format("Username:{0} logged in", authorizedUser.username));
            return RedirectToAction("Index", "Dashboard");
        }

        public ActionResult Index()
        {            
            // Redirect to default installation screen
            if (SystemSettingsContext.Settings == null)
                return RedirectToAction("Index", "Install");
            // Unlock all old locks and check if ip is still locked, redirect to locked message page
            LockContext.Unlock(Request.UserHostAddress);
            if (LockContext.IsLocked(Request.UserHostAddress))
                return RedirectToAction("IpLocked");
            try
            {
                string loginCookieData = FindCookie(LogonCookieName).ToString();
                Dal.User usr = GetUserFromLoginCookie(loginCookieData);
                if( usr != null)
                {
                    return AuthorizeUserAndSetCookie(usr.username);
                }
            }
            catch {}                        

            return View();    
        }

        [HttpPost]
        public ActionResult Index(LogonViewModel model)
        {
            // Unlock all old locks and if ip address is still locked, redirect to locked message page
            LockContext.Unlock(Request.UserHostAddress);
            if (LockContext.IsLocked(Request.UserHostAddress))
                return RedirectToAction("IpLocked");
            
            if (ModelState.IsValid)
            {            
                if (UserContext.Validate(model.Username, model.Password,model.Domain))
                {
                    // Remove logon counter object
                    SessionManager.FreeSessionObject(LogonAttemptCounterKey);
                    // If using validation from active directory domain, disable remember me option
                    return AuthorizeUserAndSetCookie(model.Username, model.Domain,String.IsNullOrEmpty(model.Domain) ? false : model.RememberMe);
                }                
                if (!SessionManager.CheckSessionObject(LogonAttemptCounterKey))
                    SessionManager.RegisterSessionObject(LogonAttemptCounterKey, 1);
                else
                {
                    int count = (int) SessionManager.ReturnSessionObject(LogonAttemptCounterKey);
                    if (count <= SystemSettingsContext.MaxLoginAttempts)
                        SessionManager.RegisterSessionObject(LogonAttemptCounterKey, count + 1);
                    else
                    {
                        //Lock ip and remove counter from session
                        LockContext.Lock(Request.UserHostAddress,SystemSettingsContext.LoginLockDuration);
                        SessionManager.FreeSessionObject(LogonAttemptCounterKey);
                        return RedirectToAction("IpLocked");
                    }
                }
                ModelState.AddModelError("InvalidLogin",Messages.LOGON_ErrorInvalidLogin);
            }            
            return View(model);
        }

        public ActionResult Logout()
        {
            LogEvent(LogOperation.Logoff, string.Format("Username:{0} logged out", AuthorizedUser.username));
            SessionManager.Logout();
            ClearCookie(LogonCookieName);
            return RedirectToAction("Index", "Logon");
        }
        // Display user that his/her ip is locked for sometime
        public ActionResult IpLocked()
        {
            return View();
        }

        

    }
}
